package org.tinycloud.tinyjob.client.utils.secure;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;


/**
 * <p>
 * Hmac SHA256工具类，用于accessToken签名
 * </p>
 *
 * @author liuxingyu01
 * @since 2024-04-09 11:59
 */
public class HmacSha256Utils {

    private static final String ALGORITHM = "HmacSHA256";

    /**
     * 使用Hmac SHA256算法生成签名
     *
     * @param secretKey 密钥
     * @param data      待签名的数据
     * @return Base64编码的签名结果
     */
    public static String hmac(String secretKey, String data) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Mac mac = Mac.getInstance(ALGORITHM);
            mac.init(keySpec);

            byte[] signatureBytes = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(signatureBytes);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 验证签名是否有效
     *
     * @param secretKey         密钥
     * @param data              原始数据
     * @param expectedSignature 预期的签名
     * @return 签名是否有效
     */
    public static boolean verify(String secretKey, String data, String expectedSignature) {
        try {
            String actualSignature = hmac(secretKey, data);
            return actualSignature.equals(expectedSignature);
        } catch (Exception e) {
            return false;
        }
    }

    // 测试示例
    public static void main(String[] args) {
        try {
            String secretKey = "test-secret-key";
            String data = "Hello, HmacSHA256!";

            // 生成签名
            String signature = hmac(secretKey, data);
            System.out.println("生成的签名: " + signature);

            // 验证签名（正确情况）
            boolean valid = verify(secretKey, data, signature);
            System.out.println("验证结果（正确情况）: " + valid);

            // 验证签名（错误情况）
            boolean invalid = verify(secretKey, "Hello, World!", signature);
            System.out.println("验证结果（错误情况）: " + invalid);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
